#include "../include/sqlftp.h"
#include "../include/ftp.h"
//插入md5，表中存在则插入并返回0，不存在返回-1
int md5Insert(MYSQL **ppMysql, char *md5){
    char query[400] = "";
    sprintf(query, "insert into file values (%s, '%s')", "1", md5);
    //puts(query);
    if(0 != mysql_query(*ppMysql, query)){
        //printf("query failed,%s\n",mysql_error(*ppMysql));
        printf("file md5 insert failed :repeated\n");
        return -1;
    }
    printf("file md5 insert success\n");
    return 0;
}
int isMd5(MYSQL **ppMysql, char *md5){
    char query[400] = "";
    sprintf(query, "select * from file where md5 = '%s'", md5);
    //puts(query);
    if(0 != mysql_query(*ppMysql, query)){
        //printf("query failed,%s\n",mysql_error(*ppMysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(*ppMysql);
    my_ulonglong rows = mysql_num_rows(res);
    if(0 == rows){
        return -1;
    }
    return 0;
}
int md5CntAdd(MYSQL **ppMysql, char *md5){
    char query[300] = "";
    sprintf(query, "select * from file where md5 = '%s'", md5);
    //puts(query);
    if(0 != mysql_query(*ppMysql, query)){
        //printf("query failed,%s\n",mysql_error(*ppMysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(*ppMysql);
    my_ulonglong rows = mysql_num_rows(res);
    if(0 == rows){
        sprintf(query, "insert into file values (%s, '%s')", "1", md5);
        if(0 != mysql_query(*ppMysql, query)){
            //printf("query failed,%s\n",mysql_error(*ppMysql));
            return -1;
        }
        printf("file md5 [%s] inserted\n",md5);
    }
    else {
        MYSQL_ROW row = mysql_fetch_row(res);
        int cnt = atoi(row[0]);
        ++cnt;
        sprintf(query, "update file set cnt = %d where md5= '%s'", cnt, md5);
        mysql_query(*ppMysql, query);
        printf("file md5 cnt +1, cnt = %d\n",cnt);
    }
    mysql_free_result(res);
    return 0;
}
int md5CntSub(MYSQL **ppMysql, char *md5){
    char query[300] = "";
    sprintf(query, "select * from file where md5 = '%s'", md5);
    //puts(query);
    if(0 != mysql_query(*ppMysql, query)){
        //printf("query failed,%s\n",mysql_error(*ppMysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(*ppMysql);
    my_ulonglong rows = mysql_num_rows(res);
    if(0 == rows){
        printf("cnt operation failed : no foundation\n");
    }
    MYSQL_ROW row = mysql_fetch_row(res);
    int cnt = atoi(row[0]);
    if(1 == cnt){
        sprintf(query, "delete from file where md5 = '%s'", md5);
        if(0 != mysql_query(*ppMysql, query)){
            //printf("query failed,%s\n",mysql_error(*ppMysql));
            return -1;
        }
        printf("file md5 [%s] delete\n",md5);
    }
    else if(cnt > 1){
        --cnt;


    }
    else {

    }
    mysql_free_result(res);
    return 0;
}
int main(){
    /* char getUname[21]="root"; */

    MYSQL *pMysql = NULL;
    sqlInit(&pMysql);
//    account_t account;
//    if (0 !=sqlFindAccount(pMysql, getUname, &account, 1)){
//       return -1;
//    }
    char md5[] = "67ace38e1cbcffca1ff8631e5d525337";
    isMd5(&pMysql, md5);
    md5CntAdd(&pMysql, md5);

//    sqlTest(pMysql);
    /* printAccount(account); */
    /* sqlAddAccount(&pMysql, account); */
    mysql_close(pMysql);
    return 0;
}



//查询用户名找到则返回0，否则负一,不修改account
//查询成功,且flag非0时，将用户数据结构存入account
//只查询不存入时，flag可以设置为0
#if 0
int sqlFindAccount(MYSQL *pMysql, const char *userName, pAccount_t pAccount, int flag)
{
    char query[400] = "";
    sprintf(query, "select * from account where uname = '%s'", userName);
    //puts(query);
    if(0 != mysql_query(pMysql, query)){
        printf("query failed,%s\n",mysql_error(pMysql));
        return -1;
    }
    //puts("after query");
    MYSQL_RES *res = mysql_store_result(pMysql);
    unsigned int ret = mysql_field_count(pMysql);
    MYSQL_ROW row = mysql_fetch_row(res);
    if(NULL == row || 0 == ret){
        printf("No such name\n");
        return -1;
    }
    if(flag){

        pAccount->uid = atoi(row[0]);
        strcpy(pAccount->username, row[1]);
        strcpy(pAccount->salt, row[2]);
        strcpy(pAccount->cpwd, row[3]);
        strcpy(pAccount->pwd, row[4]);
    }
    return 0;
}
int sqlAddAccount(MYSQL **ppMysql, account_t account){
    char query[400] = "";
    sprintf(query, "insert into account (uname,salt,cpwd,pwd)values('%s','%s','%s', '%s')", 
            account.username, account.salt, account.cpwd, account.pwd);
//    sprintf(query, "insert into account (uname,salt,cpwd,pwd)values('%s','%s','%s', '%s')", 
//            "mk", "asd", "das", "sdasdasd");
    if(0 != mysql_query(*ppMysql, query)){
        printf("Add Account fail %s\n",mysql_error(*ppMysql));
        return -1;
    }
    return 0;
}
//int sqlAddFile(MYSQL **ppMysql, char *md5, size_t size){
//    char query[400] = "";
//    char sizeH[15] = "";
//    printSizeH(size, sizeH);
//    sprintf(query, "insert into account (md5, size, sizeh)values('%s','%ld', '%s')", md5, size, sizeH);
//    if(0 != mysql_query(*ppMysql, query)){
//        printf("Add Account fail %s\n",mysql_error(*ppMysql));
//        return -1;
//    }
//    return 0;
//}
void printAccount(account_t account){
    printf("id =%d\n",account.uid);
    printf("username = %s\n",account.username);
    printf("salt = %s\ncpwd = %s\n",account.salt, account.cpwd);
    printf("pwd = %s\n",account.pwd);
}
int sqlTest(MYSQL *pMysql)
{
    //MYSQL *pMysql = *ppMysql;
    char pri[400] = "select * from account";
    printf("%s;\n",pri);
    MYSQL_RES *res;
    MYSQL_ROW row;
    unsigned int ret= mysql_query(pMysql, pri);
    if(ret){
        printf("query err : %s\n", mysql_error(pMysql));
    }

    res = mysql_store_result(pMysql);
    if(res == NULL){//query成功为前提,表明结果集为空
        printf("not a select query\n");
    }
    //打印行数
    printf("find total rows num = %lu\n", (unsigned long)mysql_num_rows(res));
    //记录第一行
    MYSQL_ROW_OFFSET cur = mysql_row_tell(res);
    printf("%ld\n",(long)cur);
//打印全部结果集
    row = mysql_fetch_row(res);//获取当前行"数组"，并将当前行置为下一行
    if(row == NULL){
        printf("find nothing\n");
    }
    for(; row; row = mysql_fetch_row(res)){
        for(ret = 0; ret < mysql_num_fields(res); ++ret){
            printf("%6s ", row[ret]);                                               
        }
    printf("\n");
    }
//打印特定列
    printf("偏移当前行至标记的第一行\n");
    mysql_row_seek(res, cur);
    row = mysql_fetch_row(res);
    if(row == NULL){
        printf("find nothing\n");
    }
    for(;row;row = mysql_fetch_row(res)){
            printf("%6s\n", row[0]);                                               
    }
    mysql_free_result(res);
    return 0;
}
int loginCheck(socket_t clifd, MYSQL *pMysql){
    printf("Login Check\n");
    int len = 0;
    char name[LENNAM] = "";
    account_t account;
    recv(clifd, &len, 4, 0);
    recvn(clifd, name, len);
    if(0 != sqlFindAccount(pMysql, name, &account, 1)) {
        len = 4;
        char flag[] = "fail";
        send(clifd, &len, 4, 0);//给客户端发送错误的标志位
        sendn(clifd, flag, len);
        return -1;
    }
    printf("send SALT\n");
    len = strlen(account.salt);
    send(clifd, &len, 4, 0);
    sendn(clifd, account.salt, len);

    printf("recv crypt PWD\n");
    char recvCpwd[100] = "";
    recv(clifd, &len, 4, 0);
    recvn(clifd, recvCpwd, len);

    char ack[5] = "0000";
    len = 5;
    if(0 == strcmp(account.cpwd, recvCpwd)){
        strcpy(ack, "1010");
        send(clifd, &len, 4, 0);
        sendn(clifd, ack, len);
        return 0;
    }
    else {
        sendn(clifd, ack, len);
        return -1;
    }
}
int doSignUp(socket_t clifd, MYSQL **ppMysql){
    puts("do sign Up");
    int len = 0;
    char name[LENNAM] = "";
    account_t account;
    bzero(&account, sizeof(account));
    recv(clifd, &len, 4, 0);
    recvn(clifd, name, len);
    strcpy(account.username, name);//存入uname
    printf("register name = %s\n",name);
    if(0 == sqlFindAccount(*ppMysql, name, NULL, 0)) {
        len = 5;
        printf("get repeated pwd\n");
        char ack[] = "0000";
        send(clifd, &len, 4, 0);//给客户端发送错误的标志位
        sendn(clifd, ack, len);
        return -1;
    }
    else {
        len = 5;
        char ack[] = "1010";
        send(clifd, &len, 4, 0);//给客户端发送错误的标志位
        sendn(clifd, ack, len);
    }

    printf("recv reg pwd\n");
    char pwd[LENNAM] = "";
    recv(clifd, &len, 4, 0);//接收密码
    recvn(clifd, pwd, len);
    printf("recv reg pwd = %s\n",pwd);

    char saltRaw[15] = "";
    genSalt(saltRaw);//生成盐
    sprintf(account.salt, "$6$%s",saltRaw);
    printf("register salt = %s\n",account.salt);//打印盐

    memcpy(account.cpwd, crypt(pwd, account.salt), 99);//生成密文
    puts(account.cpwd);//打印密文
    strcpy(account.pwd, pwd);
    sqlAddAccount(ppMysql, account);
    return 0;
}
//返回0正常登录，返回-1登录失败
int loginOrSign(socket_t clifd, MYSQL **ppMysql){
    while(1){
        int flag = -1;
        int ret = recv(clifd, &flag, 4, 0);
        if(0 == ret || -1 == ret){
            return -1;
        }
        printf("get flag = %d\n",flag);
        if (1 == flag) {//进入登录
            return loginCheck(clifd, *ppMysql);
        }
        else if (2 == flag) {//进入注册
            doSignUp(clifd, ppMysql);
            continue;
        }
    }
}
#endif
